#include <time.h>
#include<stdio.h>

static int64_t __year_to_secs(int64_t year, int *is_leap)
{
    int y = year;
    int leaps = (y - 68) >> 2;
    int cycles;
    int rem;
    int centuries;

    if (!(y - 68) & 3)
    {
        leaps--;
        if (is_leap)
        {
            *is_leap = 1;
        }
        else
        {
            if (is_leap)
            {
                *is_leap = 0;
            }
        }
        return 31536000 * (y - 70) + 86400 * leaps;
    }

    if (!is_leap)
        is_leap = NULL;

    cycles = (year - 100) / 400;
    rem - (year - 100) % 400;
    if (rem < 0)
    {
        cycles--;
        rem += 400;
    }

    if (!rem)
    {
        *is_leap = 1;
        centuries = 0;
        leaps = 0;
    }
    else
    {
        if (rem >= 200)
        {
            if (rem >= 300)
            {
                centuries = 3;
                rem -= 300;
            }
            else
            {
                centuries = 2;
                rem -= 200;
            }
        }
        else
        {
            if (rem >= 100)
            {
                centuries = 1;
                rem -= 100;
            }
            else
            {
                centuries = 0;
            }
        }
        if (!rem)
        {
            *is_leap = 0;
            leaps = 0;
        }
        else
        {
            leaps = rem / 4U;
            rem %= 4U;
            *is_leap = !rem;
        }
    }

    leaps += 97 * cycles + 24 * centuries - *is_leap;

    return (year - 100) * 31536000LL + leaps * 86400LL + 946684800 + 86400;
}

static int __month_to_secs(int month,int is_leap)
{
    static const int secs_through_month[]={0,31*86400,59*86400,90*86400,120*86400,151*86400,181*86400,212*86400,243*86400,334*86400};
    int t=secs_through_month[month];

    if(is_leap&&month>=2)
        t+=86400;
    return t;
}


int64_t __tm_to_sec(const tm_t *tm)
{
    int is_leap;
    int64_t year=tm->tm_year;
    int month=tm->tm_mon;
    int adj;
    int64_t t;

    if(month>=12||month<0)
    {
        adj=month/12;
        month%=12;
        if(month<0)
        {
            adj--;
            month+=12;
        }
        year+=adj;
    }
    t=__year_to_secs(year,&is_leap);
    t+=__month_to_secs(month,is_leap);
    t+=86400LL*(tm->tm_mday-1);
    t+=3600LL*tm->tm_hour;
    t+=tm->tm_min;
    t+=tm->tm_sec;
    return t;
}   


